package com.um.swing.component;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.um.swing.*;
import com.um.swing.ThreadPool;
import com.um.swing.bean.ConfigBean;
import com.um.swing.bean.ConfigPostionSetBean;
import com.um.swing.bean.ImageItem;
import com.um.swing.common.util.AlphanumComparator;
import com.um.swing.common.util.MessageUtil;
import com.um.swing.core.ImageJoinCore;
import com.um.swing.dialog.JExportDialog;
import com.um.swing.dialog.JJoinSettingBckDialog;
import com.um.swing.dialog.JLoadDialog;
import com.um.swing.common.inc.Config;
import com.um.swing.common.inc.Constant;
import com.um.swing.ui.*;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.Timer;

/**
 * 名称：古籍拼版面板
 * 创建人：袁泉
 * 创建时间：2022年04月30日17:36:47
 */
public class TabGujiJoinPanel extends Panel {
    private static final long serialVersionUID = 5417989883734105715L;
    public static Object LOCK = new Object();
    private JLabel jBottomInfoLabel = null;
    private JLabel jBottomZoomLabel = null;
    private JButton jPrevBtn = null;
    private JButton jNextBtn = null;
    public JButton jPreviewBtn;//预览按钮
    //底部状态栏 4个点位的lable
    private JBottomPointInfoPanel jBottomPointInfoPanel;
    //文件列表滚动容器相关控件
    public JScrollPane jFileScrollPanle = null;
    public JScrollBar jFileScrollVbar = null;
    public JScrollBar jFileScrollHbar = null;
    private MainView jMainView = null;

    private JImagePane jImagePanle = null;
    public JScrollPane scrollPane = null;
    public JScrollBar jScrollBarV = null;
    public JScrollBar jScrollBarH = null;


    //配置操作类
    private Config mCfg = Config.getInstance();
    private String mCurProjectPath = null;//当前项目的路径
    private String mWorkspace;//项目名称

    private JList<ImageItem> jfileList = new JList<ImageItem>(new DefaultListModel<ImageItem>());

    //数据集
    private List<ImageItem> mImageList = new ArrayList<ImageItem>();
    private int mCurSelectInex = 90;

    public TabGujiJoinPanel(MainView jMainView) {
        this.jMainView = jMainView;
        this.setLayout(new BorderLayout());
        //工具栏按钮
        initToolBarUI();
        //初始化图片面板UI
        initImagePanelUI();
        //初始化文件列表
        initFilePanelUI();
        //底部信息状态
        initBottomInfoUI();

        this.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
//                setScrollPaneSize(getWidth(), getHeight());
//                Dimension size = scrollPane.getSize();
//                jImagePanle.resetOrinSize(size.width, size.height);
            }
        });
    }

    //初始化文件列表
    private void initFilePanelUI() {
        // 文件列表
        jFileScrollPanle = new JScrollPane(null);
        jFileScrollPanle.setBounds(0, 0, 200, 450);
        jFileScrollPanle.setFocusTraversalKeysEnabled(true);
        jFileScrollPanle.setPreferredSize(new Dimension(200, 100));
        jfileList.addListSelectionListener(t -> {
            int selectedIndex = jfileList.getSelectedIndex();
            if (selectedIndex == -1) {
                return;
            }
            mCfg.updateCurIndex(selectedIndex);
            boolean preview = mImageList.get(selectedIndex).isPreview();
            jPreviewBtn.setText(preview ? "取消预览" : "预览");
            if (mCurSelectInex != selectedIndex) {
                toImageByIndex(selectedIndex, false);

            }
        });
        jfileList.setBackground(new Color(59, 63, 65));
        jfileList.setCellRenderer(new FileListCellRenderer());
        jFileScrollPanle.setViewportView(jfileList);
        jFileScrollPanle.setUI(new IScrollPaneUI());
        jFileScrollVbar = jFileScrollPanle.getVerticalScrollBar();
        jFileScrollHbar = jFileScrollPanle.getHorizontalScrollBar();
//        jFileScrollHbar.setUI(new IScrollBarUI());
//        jFileScrollVbar.setUI(new IScrollBarUI());
        this.add(jFileScrollPanle, BorderLayout.WEST);
    }

    //初始化图片面板UI
    private void initImagePanelUI() {
        jImagePanle = JImagePane.getInstance();
        jImagePanle.setjTabGujiJoinPanel(this);
        jImagePanle.setPointClickEvent(t -> pointClickEvent(t));
        scrollPane = new JScrollPane(jImagePanle);
        scrollPane.setUI(new IScrollPaneUI());
        jScrollBarV = scrollPane.getVerticalScrollBar();
        jScrollBarH = scrollPane.getHorizontalScrollBar();
//        jScrollBarV.setUI(new IScrollBarUI());
//        jScrollBarH.setUI(new IScrollBarUI());
        setScrollPaneSize(getWidth(), getHeight());
        jImagePanle.setjScrollVbar(jScrollBarV, jScrollBarH);
        this.add(scrollPane, BorderLayout.CENTER);
    }

    //底部信息状态
    private void initBottomInfoUI() {
        jBottomInfoLabel = createBottomStatusJLabel();
        jBottomInfoLabel.setText(Constant.LABLE_TEXT);
        jBottomInfoLabel.setPreferredSize(new Dimension(190, Constant.TOOL_BAR_HEIGHT));
        jBottomZoomLabel = createBottomStatusJLabel();
        jBottomPointInfoPanel = new JBottomPointInfoPanel();
        jBottomPointInfoPanel.setClickEvent(t -> bottomIndexClick(t));

        JPanel bpane = new JPanel();
        bpane.add(jBottomInfoLabel);
        bpane.setUI(new IBottomPanleUI());
        bpane.add(new JSeparator());
        bpane.add(jBottomZoomLabel);
        bpane.add(jBottomPointInfoPanel);
        this.add(bpane, BorderLayout.SOUTH);
    }

    //底部点位信息点击事件
    private Object bottomIndexClick(Integer index) {
        ImageItem item = mImageList.get(mCurSelectInex);
        if (item.isPreview()) {
            //如果是预览状态，则不加载点位置配置
            return null;
        }
        //设置当前点应有的配置
        ConfigBean cfgObject = mCfg.getCfgObject();
        ImageItem cfgItem = cfgObject.getImageData().get(item.getName());

        if ((cfgObject.getPostionSettingMapSize() < index) && (cfgItem == null || cfgItem.getPostionSettingMapSize() < index)) {
            return null;
        }
        //优先使用点位上的配置
        ConfigPostionSetBean posCfg = cfgObject.getPosSettingItem(index - 1);
        ConfigPostionSetBean itemPosCfg = cfgItem.getPosSettingItem(index - 1);

        SwingUtilities.invokeLater(() -> jImagePanle.setZoom(itemPosCfg == null || itemPosCfg.getZoomValue() == 1 ? posCfg.getZoomValue() : itemPosCfg.getZoomValue()));
        new Timer().schedule(new TimerTask() {//延迟100毫秒是需要等setZoom刷新UI
            @Override
            public void run() {
                SwingUtilities.invokeLater(() -> {
                    int vValue = itemPosCfg == null || itemPosCfg.getvScrollValue() == 0 ? posCfg.getvScrollValue() : itemPosCfg.getvScrollValue();
                    jScrollBarV.setValue(Math.max(vValue, JImagePane.PADDING_NUM / 2));
                    if (itemPosCfg != null && itemPosCfg.gethScrollValue() != 0) {
                        jScrollBarH.setValue(itemPosCfg.gethScrollValue());
                    } else {
                        if (isTow(mCurSelectInex)) {
                            jScrollBarH.setValue(jScrollBarH.getMaximum());
                        } else {
                            jScrollBarH.setValue(posCfg.gethScrollValue());
                        }
                    }
                });
            }
        }, 100);
        return null;
    }

    //工具栏按钮
    private void initToolBarUI() {
        JToolBar tool = new JToolBar();
//        tool.setLayout(new FlowLayout(5, 5, FlowLayout.LEFT));
        tool.setFloatable(false);
        tool.setUI(new IToolBarUI());

        //打开项目按钮
        JButton openBtn = new JButton("打开项目");
        openBtn.setUI(new IButtonUI(Constant.TEXT_BUTTON_SIZE_W70, null));
        openBtn.addActionListener(t -> openNewWorkspace(t, true));
        tool.add(openBtn);


        jPrevBtn = new JButton("上一张");
        jPrevBtn.setUI(new IButtonUI(Constant.B_BUTTON_SIZE, IButtonUI.B_ICON.PREVIOUS));
        jPrevBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        prev();
                    }
                });
            }
        });
        jNextBtn = new JButton("下一张");
        jNextBtn.setUI(new IButtonUI(Constant.B_BUTTON_SIZE, IButtonUI.B_ICON.NEXT));
        jNextBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        next();
                    }
                });
            }
        });
        tool.add(jPrevBtn);
        tool.add(jNextBtn);
        tool.addSeparator();

        //zoom in out
        JButton zoom_in = new JButton();
        zoom_in.setUI(new IButtonUI(Constant.M_BUTTON_SIZE, IButtonUI.B_ICON.ZOOM_IN));
        zoom_in.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        jImagePanle.larger(JImagePane.CLICK_ZOOM_OFFSET);
                    }
                });
            }
        });
        JButton zoom_out = new JButton();
        zoom_out.setUI(new IButtonUI(Constant.M_BUTTON_SIZE, IButtonUI.B_ICON.ZOOM_OUT));
        zoom_out.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        jImagePanle.smaller(JImagePane.CLICK_ZOOM_OFFSET);
                    }
                });
            }
        });
        JButton rsize = new JButton();
        rsize.setUI(new IButtonUI(Constant.M_BUTTON_SIZE, IButtonUI.B_ICON.FIT_BEST));
        rsize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        jImagePanle.self();
                    }
                });
            }
        });
        tool.add(zoom_in);
        tool.add(zoom_out);
        tool.add(rsize);
        tool.addSeparator();

        //预览按钮
        JButton jOpenProjectBtn = new JButton("打开文件夹");
        jOpenProjectBtn.setUI(new IButtonUI(Constant.TEXT_BUTTON_SIZE_W80, null));
        jOpenProjectBtn.addActionListener(t -> openProjectFolderEvent());
        tool.add(jOpenProjectBtn);

        //设置按钮
        JButton jProjectSetBtn = new JButton("项目设置");
        jProjectSetBtn.setUI(new IButtonUI(Constant.TEXT_BUTTON_SIZE_W80, null));
        jProjectSetBtn.addActionListener(t -> projectSettingEvent());
        tool.add(jProjectSetBtn);

        //预览按钮
        jPreviewBtn = new JButton("预 览");
        jPreviewBtn.setUI(new IButtonUI(Constant.TEXT_BUTTON_SIZE_W70, null));
        jPreviewBtn.addActionListener(t -> previewEvent());
        tool.add(jPreviewBtn);
        //生成按钮
        JButton resetBtn = new JButton("导 出");
        resetBtn.setUI(new IButtonUI(Constant.TEXT_BUTTON_SIZE_W70, null));
        resetBtn.addActionListener(t -> exportEvent());
        tool.add(resetBtn);

        this.add(tool, BorderLayout.NORTH);
    }

    //项目设置按钮点击事件
    private void projectSettingEvent() {
        JJoinSettingBckDialog.getInstance().setVisible(true);

    }

    //导出按钮点击事件
    private void exportEvent() {
        if (StrUtil.isBlank(mCurProjectPath)) {
            MessageUtil.alert(this, "未打开项目，无法进行导出");
            return;
        }
        String targetPath = mCurProjectPath + File.separator + "导出结果";
        File targetFile = new File(targetPath);
        JExportDialog exportDialog = JExportDialog.getInstance();
        if (!exportDialog.isExportIng() && targetFile.exists()) {
            int res = MessageUtil.confirm(null, "已存在导出文件，导出将覆盖之前导出的文件，请问是否继续？");
            if (res == 0) {
                FileUtil.del(targetFile);
            } else {
                return;
            }
        }
        FileUtil.mkdir(targetFile);
        exportDialog.tryStartExport(mImageList, targetFile);
    }


    /**
     * 查看下一张图片
     */
    public void next() {
        if (mImageList.size() == 0) return;
        JLoadDialog.getInstance().showDialog();
        synchronized (LOCK) {
            mCurSelectInex++;
            if (mCurSelectInex > mImageList.size() - 1)
                mCurSelectInex = 0;
            toImageByIndex(mCurSelectInex, true);
        }
    }

    /**
     * 查看上一张
     */
    public void prev() {
        if (mImageList.size() == 0) return;
        JLoadDialog.getInstance().showDialog();
        synchronized (LOCK) {
            mCurSelectInex--;
            if (mCurSelectInex < 0)
                mCurSelectInex = mImageList.size() - 1;
//            jFileScrollVbar.setValue(jFileScrollVbar.getValue()-27);
            toImageByIndex(mCurSelectInex, true);

        }
    }

    /**
     * 跳转到指定张
     *
     * @param selectedIndex
     */
    private void toImageByIndex(Integer selectedIndex, boolean isSelectFile) {
        if (selectedIndex == -1) {
            return;
        }
        if (mImageList.size() == 0) {
            return;
        }
        if (mCurSelectInex != selectedIndex) {
            mCurSelectInex = selectedIndex;
        }

        if (isSelectFile) {
            jfileList.setSelectedIndex(mCurSelectInex);
        }
        JLoadDialog.getInstance().showDialog();
        ThreadPool.execute(() -> {
            ImageItem item = mImageList.get(mCurSelectInex);
            ImageIcon icon = null;
            if (item.isPreview() && item.getPreviewImage() != null) {
                icon = new ImageIcon(item.getPreviewImage());
            } else {
                icon = new ImageIcon(item.getPath());

                if (icon.getIconWidth() == -1) {
                    try {
                        BufferedImage read = ImageIO.read(new File(item.getPath()));
                        icon = new ImageIcon();
                        icon.setImage(read);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            ImageIcon finalIcon = icon;
            SwingUtilities.invokeLater(() -> {
                setWindowTitle(item.getName());
                setLabelText(" " + finalIcon.getIconWidth() + " × " + finalIcon.getIconHeight() + " 像素   " +
                        getFileSize(mCurSelectInex));
                jImagePanle.drawPicture(finalIcon, item);
                if (!mImageList.get(selectedIndex).isPreview()) {
                    jBottomPointInfoPanel.refreshBottomPointInfo(mImageList.get(selectedIndex));
                }
            });
        });
    }

    private String getFileSize(int index) {
        File pic = new File(mImageList.get(index).getPath());
        if (pic.length() >= 1048576) {
            String str = ((float) pic.length() / 1048576) + "";
            return str.substring(0, str.indexOf('.') + 3) + "MB";
        } else if (pic.length() > 1024) {
            String str = ((float) pic.length() / 1024) + "";
            return str.substring(0, str.indexOf('.') + 3) + "KB";
        }
        return pic.length() + "B";
    }

    //面板点完4个点之后触发的事件
    public Object pointClickEvent(ImageItem item) {
        int pointIndex = item.getOldPointIndex();
        //保存当前点位的滚动条和缩放比例配置
        savePostionCfg(item);
        if (pointIndex == 4 && item.isOverPoint()) {
            if (isTow(mCurSelectInex)) {//触发预览
                previewEvent();
            } else {
                next();
            }
        }
        //该方法会 读取设置下一个点位的配置
        jBottomPointInfoPanel.refreshBottomPointInfo(item);
        return null;
    }

    //保存点位配置
    private void savePostionCfg(ImageItem item) {
        int hValue = jScrollBarH.getValue();
        int vValue = jScrollBarV.getValue();
        float zoom = jImagePanle.getZoom();
        int pointIndex = item.getOldPointIndex();
        //全局位置的配置
        ConfigBean cfgObject = mCfg.getCfgObject();
        ConfigPostionSetBean postionSetBean = cfgObject.getPosSettingItem(pointIndex - 1);
        postionSetBean.setvScrollValue(vValue);
        //如果是第二页的话，则不更新横向滚动条的位置
        if (!isTow(mCurSelectInex)) {
            postionSetBean.sethScrollValue(hValue);
        }
        postionSetBean.setZoomValue(zoom);
        //点位配置
        ImageItem cfgItem = mCfg.updateImageItem(item, false);
        ConfigPostionSetBean cfgPosSet = cfgItem.getPosSettingItem(pointIndex - 1);
        if (cfgPosSet.gethScrollValue() == 0) {
            cfgPosSet.setvScrollValue(vValue);
            cfgPosSet.sethScrollValue(hValue);
            cfgPosSet.setZoomValue(zoom);
        }
        Config.getInstance().save();
    }

    /**
     * 打开一个新的项目
     *
     * @param e
     */
    private void openNewWorkspace(ActionEvent e, boolean isAwt) {
        if (isAwt) {
            FileDialog dialog = new FileDialog(new JFrame(), "请选择目录", FileDialog.LOAD);
            dialog.setVisible(true);
            dialog.setMultipleMode(false);
            String directory = dialog.getDirectory();
//            System.out.println(directory);
            if (StrUtil.isNotBlank(directory)) {
                openNewWorkspace(new File(directory));
            }
        } else {
            JFileChooser chooser = new JFileChooser();
            chooser.setFileHidingEnabled(true);
            chooser.setDialogTitle("请选择工作目录");
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            chooser.setAcceptAllFileFilterUsed(false);
            chooser.setFileFilter(new FileNameExtensionFilter("请选择目录", "png", "jpg", "jpeg"));
            chooser.setVisible(true);
            int result = chooser.showOpenDialog((Component) e.getSource());
            if (result == JFileChooser.APPROVE_OPTION) {
                File file = chooser.getSelectedFile();
                openNewWorkspace(file);
            }
        }
    }


    private void openNewWorkspace(File dir) {
        if (dir == null || !dir.exists()) {
            MessageUtil.alert(this, "目录不能为空");
        }
        String path = dir.getAbsolutePath();
        //如果选择的目录和当前已加载的目录不一致，则打开新的项目
        if (StrUtil.isNotBlank(mCurProjectPath)) {
            if (path.equals(mCurProjectPath)) {
                MessageUtil.alert(null, "当前已打开此项目");
                return;
            }
            int result = MessageUtil.confirm(null, "您将打开新的项目，是否保存当前的拼版数据", JOptionPane.YES_NO_CANCEL_OPTION);
            if (result == 0) {
                mCfg.save();
            } else if (result == 2) {
                //取消：不打开新的项目了
                return;
            }
        }
        mWorkspace = dir.getName();
        setWindowTitle(null);
        ConfigBean cfgBean = mCfg.initConfig(mWorkspace, dir.getPath());
        mCurProjectPath = path;
        mImageList.clear();
        jfileList.clearSelection();
        String[] names = dir.list(new IFileFilter());
        DefaultListModel<ImageItem> fileListModel = (DefaultListModel<ImageItem>) jfileList.getModel();
        fileListModel.clear();
        fileListModel.removeAllElements();
        jImagePanle.clear();
        if (names.length == 0) {
            mCurSelectInex = -1;
            JOptionPane.showMessageDialog(null, "该目录内无图片数据", "系统提示", JOptionPane.YES_OPTION);
        } else {
            List<String> fileNameList = Arrays.asList(names);
            Collections.sort(fileNameList, new AlphanumComparator());
            Map<String, ImageItem> cfgImgData = cfgBean.getImageData();
            for (int j = 0; j < fileNameList.size(); j++) {
                String fileName = names[j];
                ImageItem cfgItem = cfgImgData.get(fileName);
                ImageItem item;
                item = cfgItem != null ? cfgItem
                        : new ImageItem(mCurProjectPath + File.separator + fileName, fileName);
                mImageList.add(item);
                fileListModel.addElement(item);
            }
            //根据配置初始化数据 cfgBean
            this.mCurSelectInex = cfgBean.getCurProcIndex() - 1;
        }
        jfileList.setModel(fileListModel);
        jfileList.repaint();
        next();
    }

    //设置当前窗口的标题
    private void setWindowTitle(String title) {
        StringBuffer sb = new StringBuffer();
        if (StrUtil.isNotBlank(mWorkspace)) {
            sb.append("[").append(mWorkspace).append("]");
        }
        if (StrUtil.isNotBlank(title)) {
            sb.append("- ").append(title).append(" ");
        }
        sb.append(Constant.W_TITLE);
        jMainView.setTitle(sb.toString());
    }

    private boolean isTow(int sIndex) {
        return sIndex % 2 != 0;
    }

    //打开项目文件夹点击事件
    private void openProjectFolderEvent() {
        if (StrUtil.isBlank(mCurProjectPath)) {
            MessageUtil.alert(jMainView, "未打开项目，无法打开项目所在文件夹");
            return;
        }
        try {
            Desktop.getDesktop().open(new File(mCurProjectPath));
        } catch (Exception e) {
            e.printStackTrace();
            MessageUtil.alert(jMainView, "发生错误，打开文件夹失败(" + e.getMessage() + ")");
        }
    }

    //预览按钮点击事件
    public void previewEvent() {
        if (StrUtil.isBlank(mWorkspace)) {
            MessageUtil.alert(this, "当前未选择项目，请选择项目后再进行操作");
            return;
        }
        int sIndex = jfileList.getSelectedIndex();
        if (sIndex == -1) {
            MessageUtil.alert(this, "请选择一张图片进行预览");
            return;
        }

        boolean isTow = isTow(sIndex);
        ImageItem item = mImageList.get(sIndex);
        ImageItem prvItem = mImageList.get(isTow ? sIndex - 1 : sIndex + 1);

        if (item.isPreview()) {//如果已经是预览状态，则退出预览
            item.setPreview(false);
            prvItem.setPreview(false);
            jPreviewBtn.setText("预览");
            toImageByIndex(sIndex, true);
            return;
        }
        if (!item.isOverPoint() || !prvItem.isOverPoint()) {
            MessageUtil.alert(this, "当前拼接组未进行定位完成");
            return;
        }

        Image image;
        try {
            image = ImageJoinCore.imageJoin(isTow ? prvItem : item, isTow ? item : prvItem, this);
        } catch (Exception e) {
            e.printStackTrace();
            MessageUtil.alert(this, "图片处理异常," + e.getMessage());
            return;
        }
        item.setPreviewImage(image);
        item.setPreview(true);
        prvItem.setPreviewImage(image);
        prvItem.setPreview(true);
        jPreviewBtn.setText("取消预览");
        toImageByIndex(sIndex, true);
    }

    /**
     * set the size of the ScrollPane
     */
    public void setScrollPaneSize(int width, int height) {
        Dimension size = new Dimension(width - 8,
                height - Constant.MENU_BAR_HEIGHT - IToolBarUI.TOOL_BAR_HEIGHT -
                        IMenuBarUI.JCOMPONENT_HEIGHT - Constant.WIND_BOR_HEIGHT);
        scrollPane.setPreferredSize(size);
        scrollPane.setSize(size);
    }

    /**
     * append text to the statu bar
     */
    public void setPercent(float per) {
        String str = (per * 100) + "";
        jBottomZoomLabel.setText(str.substring(0, str.indexOf('.')) + "%");
    }

    public void setLabelText(String str) {
        jBottomInfoLabel.setText(str);
    }


    private JLabel createBottomStatusJLabel() {
        JLabel label = new JLabel();
        label.setOpaque(false);
        label.setFont(Constant.FONT_BASE_12);
        label.setBorder(new EmptyBorder(0, 0, 0, 0));
        label.setForeground(Constant.MAIN_FR_COLOR);
        return label;
    }
}
